package com.xunfang.aspect;

import com.xunfang.utils.LogUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author yellow Docter
 * @date 2023 -11-10
 * @desc
 *     通知：方法增强的代码 (重复抽取的代码)
 *          前置通知   增强代码在方法前执行  (目标方法)
 *          后置通知   增强代码在方法后执行  (目标方法)
 *
 *    ProceedingJoinPoint: 连接点
 *          目标方法 + 通知
 */
@Aspect      //定义切面类     通知 和 增强方法的整合 类
@Component
public class LogAspect {

    @Autowired
    private LogUtils logUtils;

    //切点   (对个方法进行增强)

    /**             修饰符  包下面的类.具体的类.方法(参数)
     *  原始的切点: public com.xunfang.service.impl.StuService.study(int score)
     *  优化的切点: * com.xunfang.service.impl.StuService.study(..)
     *  类优化(所有方法)的切点: * com.xunfang.service.impl.StuService.*(..)
     *  包下面的类优化(所有方法)的切点: * com.xunfang.service.impl.*.*(..)
     *
     *
     */
    @Pointcut("execution(* com.xunfang.service.impl.*.*(..))")
    public void pt(){}

    // Before  前置通知     在目标方法之前执行
//    @Before(value = "pt()")   //你的通知用在那个方法上面
//    public void before(){
//        logUtils.log("我是日志:我是前置通知...");
//    }
//
//    // Before  后置通知     在目标方法执行之后
//    @After(value = "pt()")   //你的通知用在那个方法上面
//    public void After(){
//        logUtils.log("我是日志:我是后置通知...");
//    }

    //环绕通知    环绕通知     在目标方法前后 执行
    //  1、有返回值       2、连接点 ( 目标方法 + 通知 )
    @Around(value = "pt()")
    public Object around(ProceedingJoinPoint pjp){

        //执行目标方法
        Object result = null;
        try {
            logUtils.log("我是日志:我在目标方法前执行 通知...");
            result = pjp.proceed();

            logUtils.log("我是日志:===> 我在目标方法后执行 通知...");
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }

        return result;
    }

}
